package com.objectdraw.client.objectdraw;
import java.awt.*;
import java.awt.event.*;
import com.objectdraw.client.*;
import javax.swing.*;
import java.util.EventListener;

/**
 * The drawing canvas holds the image and image buffer .  It also holds some
 * client wide states and the objects drawn on the canvas.
 * 
 * @author jgulik, cfruehan
 *
 */
@SuppressWarnings("serial")
public class DrawingCanvas extends JComponent {

	protected Image imageBuffer;
	protected Graphics imageBufferGraphics;
	public IDrawingObjectLink firstObject;
	public IDrawingObjectLink lastObject;
	protected int canvasWidth;
	protected int canvasHeight;
	protected Color penColor = Color.black;
	public Tool currentTool;
	public SelectionBox magicBox;
	public clientcomm com;
	public boolean control;

	/**
	 * instantiates and initializes the canvas
	 */
	public DrawingCanvas() {
		setCurrentTool(new FreehandTool(this));
		setBackground(Color.white);
		firstObject=null;
		lastObject=null;
		magicBox=new SelectionBox(this);
		control=true;
	}
	/**
	 * adds myObj to list of objects on the canvas
	 * @param myObj
	 */
	public void push(IDrawingObjectLink myObj){
		myObj.next=firstObject;
		if(firstObject==null){
			lastObject=myObj;
		}else{
			firstObject.prev=myObj;
		}
		firstObject=myObj;
	}


	protected void addDrawingCanvasListener(EventListener listener) {
		addMouseListener((MouseListener) listener);
		addMouseMotionListener((MouseMotionListener) listener);
	}

	public void addKeyboardListener(EventListener listener) {
		addKeyListener( (KeyListener)listener);
	}

	/**
	 * calls paint(g)
	 */
	public void update(Graphics g){
		paint(g);
	}
	/**
	 * draws the list of objects to the canvas
	 */
	public void paint(Graphics g) {
		IDrawingObjectLink current=lastObject;
		while(current!=null){
			current.o.drawMe(imageBufferGraphics);
			current=current.prev;
		}
		if(currentTool.getClass() != SelectTool.class)magicBox.active=false;
		magicBox.drawMe(imageBufferGraphics);
		g.drawImage(imageBuffer,0, 0, this);
		imageBuffer = createImage(canvasWidth, canvasHeight);
		imageBufferGraphics = imageBuffer.getGraphics();
	}

	/**
	 * draws a line on the canvas.  re-implements elsewhere.
	 * 
	 * @param p1 line starting point
	 * @param p2 line ending point
	 */
	public void drawLineSegment(Point p1, Point p2) {
		imageBufferGraphics.drawLine(p1.x,p1.y,p2.x, p2.y);
		repaint();
	}

	/**
	 * resets bounds of drawing canvas.
	 */
	public void setBounds(int x, int y, int width, int height) {
		if(width<=0)width=1;
		if(height<=0)height=1;
		imageBuffer = createImage(width, height);
		imageBufferGraphics = imageBuffer.getGraphics();

		super.setBounds(x, y, width, height);
		repaint();
		canvasWidth = width;
		canvasHeight = height;
	}
	/**
	 * changes the color of the pen to c
	 * @param c color is set to this
	 */
	public void setPenColor(Color c) {
		penColor = c;
		imageBufferGraphics.setColor(penColor);
	}

	/**
	 * empties the list of objects on the canvas and the repaints
	 */
	public void clearCanvas() {
		imageBuffer = createImage(canvasWidth, canvasHeight);
		imageBufferGraphics = imageBuffer.getGraphics();
		firstObject=null;
		lastObject=null;
		repaint();
	}



	/**
	 * returns the imagebuffer
	 * @return
	 */
	public Graphics getImageBufferGraphics() {
		return imageBufferGraphics; 
	}

	/**
	 * returns current tool
	 * @return
	 */
	public Tool getCurrentTool() {
		return currentTool;
	}

	/** 
	 * sets the current tool
	 * @param tool
	 */
	public void setCurrentTool(Tool tool) {
		currentTool = tool;
	}
	
	/**
	 * overloaded method used to set current tool when param is a string 
	 * @param tool
	 */
	public void setCurrentTool(String tool) {
		if(tool.equalsIgnoreCase("line")){
			currentTool = new LineTool(this);
		}else if(tool.equalsIgnoreCase("rectangle")){
			currentTool = new RectangleTool(this);
		}else if(tool.equalsIgnoreCase("oval")){
			currentTool = new OvalTool(this);
		}else if(tool.equalsIgnoreCase("selection")){
			currentTool = new SelectTool(this);
		}else if(tool.equalsIgnoreCase("text")){
			currentTool = new TextTool(this);
		}else{
			currentTool = new FreehandTool(this);
		}
	}
}
